package com.kexio.user.service.impl;

import java.util.List;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kexio.user.entity.RoleMenu;
import com.kexio.user.entity.UserRole;
import com.kexio.user.mapper.RoleMenuMapper;
import com.kexio.user.mapper.UserMapper;
import com.kexio.user.mapper.UserRoleMapper;
import com.kexio.user.service.PermissionVersionService;

/**
 * 权限版本管理服务实现
 * 
 * 核心功能：在权限发生变化时自动递增用户的 permVersion，
 * 使前端能够及时检测到权限变化并重新加载菜单/路由
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Service
public class PermissionVersionServiceImpl implements PermissionVersionService {
    
    private static final Logger logger = LoggerFactory.getLogger(PermissionVersionServiceImpl.class);
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean onUserRoleChanged(String userId) {
        try {
            long newVersion = System.currentTimeMillis();
            int updated = userMapper.updatePermVersionById(userId, newVersion);
            
            if (updated > 0) {
                logger.info("✅ 用户角色变更，权限版本已更新: userId={}, newVersion={}", userId, newVersion);
                return true;
            } else {
                logger.warn("⚠️ 更新用户权限版本失败（用户不存在?）: userId={}", userId);
                return false;
            }
            
        } catch (Exception e) {
            logger.error("❌ 用户角色变更时更新权限版本失败: userId={}, error={}", userId, e.getMessage(), e);
            return false;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int onRolePermissionChanged(String roleId) {
        // 查询该角色下的所有用户
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getRoleId, roleId);
        List<UserRole> userRoles = userRoleMapper.selectList(queryWrapper);
        
        if (CollectionUtils.isEmpty(userRoles)) {
            logger.info("⚠️ 角色无关联用户，跳过更新: roleId={}", roleId);
            return 0;
        }
        
        // 提取用户ID列表
        List<String> userIds = userRoles.stream()
            .map(UserRole::getUserId)
            .distinct()
            .collect(Collectors.toList());
        
        // 批量更新权限版本
        int successCount = batchIncrementVersion(userIds);
        
        logger.info("✅ 角色权限变更，批量更新用户权限版本: roleId={}, affectedUsers={}, success={}", 
            roleId, userIds.size(), successCount);
        
        return successCount;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int onMenuChanged(String menuId) {
        try {
            // 查询包含该菜单的所有角色
            LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RoleMenu::getMenuId, menuId);
            List<RoleMenu> roleMenus = roleMenuMapper.selectList(queryWrapper);
            
            if (CollectionUtils.isEmpty(roleMenus)) {
                logger.info("⚠️ 菜单无关联角色，跳过更新: menuId={}", menuId);
                return 0;
            }
            
            // 提取角色ID列表
            List<String> roleIds = roleMenus.stream()
                .map(RoleMenu::getRoleId)
                .distinct()
                .collect(Collectors.toList());
            
            logger.info("📊 菜单变更影响的角色: menuId={}, affectedRoles={}", menuId, roleIds);
            
            // 依次处理每个角色
            int totalSuccessCount = 0;
            for (String roleId : roleIds) {
                int count = onRolePermissionChanged(roleId);
                totalSuccessCount += count;
            }
            
            logger.info("✅ 菜单变更，批量更新用户权限版本: menuId={}, affectedRoles={}, totalAffectedUsers={}", 
                menuId, roleIds.size(), totalSuccessCount);
            
            return totalSuccessCount;
            
        } catch (Exception e) {
            logger.error("❌ 菜单变更时批量更新失败: menuId={}, error={}", menuId, e.getMessage(), e);
            return 0;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchIncrementVersion(List<String> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            return 0;
        }
        
        try {
            long newVersion = System.currentTimeMillis();
            int successCount = 0;
            
            for (String userId : userIds) {
                try {
                    int updated = userMapper.updatePermVersionById(userId, newVersion);
                    if (updated > 0) {
                        successCount++;
                    }
                } catch (Exception e) {
                    logger.warn("⚠️ 更新单个用户权限版本失败: userId={}, error={}", userId, e.getMessage());
                }
            }
            
            logger.debug("✅ 批量更新用户权限版本完成: total={}, success={}", userIds.size(), successCount);
            return successCount;
            
        } catch (Exception e) {
            logger.error("❌ 批量更新用户权限版本异常: userCount={}, error={}", 
                userIds.size(), e.getMessage(), e);
            return 0;
        }
    }
}

